package org.erp.store.service.impl;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.erp.common.page.PageQueryModel;

import org.erp.store.infrastructure.convert.DeviceInventoryConvert;
import org.erp.store.infrastructure.convert.DeviceRemarkConvert;
import org.erp.store.infrastructure.convert.InventoryLogConvert;
import org.erp.store.domain.entity.DeviceInventory;

import org.erp.store.domain.entity.DeviceRemark;
import org.erp.store.domain.entity.InventoryLog;
import org.erp.store.domain.dto.DeviceInventoryDto;
import org.erp.store.domain.vo.DeviceInventoryDetailsVo;
import org.erp.store.domain.vo.DeviceInventoryVo;
import org.erp.store.infrastructure.enums.DeviceInventoryState;
import org.erp.store.infrastructure.mapper.DeviceInventoryMapper;
import org.erp.store.infrastructure.mapper.DeviceRemarkMapper;
import org.erp.store.infrastructure.mapper.InventoryLogMapper;
import org.erp.store.service.DeviceInventoryService;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service("deviceInventoryService")
public class DeviceInventoryServiceImpl extends ServiceImpl<DeviceInventoryMapper, DeviceInventory> implements DeviceInventoryService {

     @Resource
     private DeviceInventoryMapper deviceInventoryMapper;

     @Resource
     private DeviceInventoryConvert deviceInventoryConvert;

     @Resource
      private InventoryLogMapper inventoryLogMapper;
     @Resource
     private InventoryLogConvert inventoryLogConvert;

     @Resource
     private DeviceRemarkMapper deviceRemarkMapper;
     @Resource
     private DeviceRemarkConvert deviceRemarkConvert;
     

     @Override
     public PageQueryModel<DeviceInventoryVo> getListByPage(DeviceInventoryDto deviceInventoryDto) {
          LambdaQueryWrapper<DeviceInventory> queryWrapper = new LambdaQueryWrapper<>();
          queryWrapper.in(deviceInventoryDto.getProductCodes() != null &&!deviceInventoryDto.getProductCodes().isEmpty(), DeviceInventory::getProductCode, deviceInventoryDto.getProductCodes())
                    .eq(StringUtils.hasText(deviceInventoryDto.getProductImei()),DeviceInventory::getProductImei,deviceInventoryDto.getProductImei())
                    .eq(StringUtils.hasText(deviceInventoryDto.getOrderNo()),DeviceInventory::getOrderNo,deviceInventoryDto.getOrderNo())
                    .eq(deviceInventoryDto.getStatus() != null,DeviceInventory::getStatus,deviceInventoryDto.getStatus())
                    .eq(deviceInventoryDto.getModelId() != null,DeviceInventory::getModelId,deviceInventoryDto.getModelId())
                    .eq(deviceInventoryDto.getLevelId() != null,DeviceInventory::getLevelId,deviceInventoryDto.getLevelId())
                    .eq(deviceInventoryDto.getTenantId() != null,DeviceInventory::getTenantId,deviceInventoryDto.getTenantId())
                    .eq(StringUtils.hasText(deviceInventoryDto.getOperateName()),DeviceInventory::getOperateName,deviceInventoryDto.getOperateName())
                    .eq(StringUtils.hasText(deviceInventoryDto.getTransferUserName()),DeviceInventory::getTransferUserName,deviceInventoryDto.getTransferUserName())
                    .eq(deviceInventoryDto.getCategoryId() != null,DeviceInventory::getCategoryId,deviceInventoryDto.getCategoryId())
                    .between(StringUtils.hasText(deviceInventoryDto.getStartTime())  &&  StringUtils.hasText(deviceInventoryDto.getEndTime()),DeviceInventory::getCreateTime,deviceInventoryDto.getStartTime(),deviceInventoryDto.getEndTime())
                    .eq(DeviceInventory::getDelFlag, 0)
                    .orderByAsc(DeviceInventory::getStatus)
                    .orderByDesc(DeviceInventory::getCreateTime);
          Page<DeviceInventory> page = this.page(deviceInventoryDto.buildPage(), queryWrapper);
          List<DeviceInventoryVo> voList = page.getRecords().stream()
                  .map(entity -> {
                      DeviceInventoryVo vo = deviceInventoryConvert.toVo(entity);
                      int base = entity.getStockDaysTotal() == null ? 0 : entity.getStockDaysTotal();
                      if (DeviceInventoryState.INBOUND.getCode().equals(entity.getStatus()) && entity.getLastInboundTime() != null) {
                          base += DateUtil.between(entity.getLastInboundTime(), new Date(), DateUnit.DAY);
                      }
                      vo.setInStockDays(base);
                      return vo;
                  }).collect(Collectors.toList());
          return PageQueryModel.of(page.getPages(), voList);
      }

   

    @Override
    public DeviceInventoryDetailsVo getDetailsByCode(String productCode) {
         DeviceInventory deviceInventory = deviceInventoryMapper.selectOne(new LambdaQueryWrapper<DeviceInventory>()
                .eq(DeviceInventory::getProductCode, productCode)
                .eq(DeviceInventory::getDelFlag, 0));
         List<InventoryLog> inventoryLogs = inventoryLogMapper.selectList(new LambdaQueryWrapper<InventoryLog>()
                .eq(InventoryLog::getProductCode, deviceInventory.getProductCode()).orderByDesc(InventoryLog::getCreateTime));
         List<DeviceRemark> deviceRemarks = deviceRemarkMapper.selectList(new LambdaQueryWrapper<DeviceRemark>()
                .eq(DeviceRemark::getProductCode, productCode).eq(DeviceRemark::getDelFlag, 0)
                 .orderByDesc(DeviceRemark::getCreateTime));
        DeviceInventoryDetailsVo vo = new DeviceInventoryDetailsVo();
        vo.setDeviceInventory(deviceInventoryConvert.toVo(deviceInventory));
        vo.setInventoryLogList(inventoryLogConvert.toInventoryLogVoList(inventoryLogs));
        vo.setDeviceRemarkList(deviceRemarkConvert.toDeviceRemarkVoList(deviceRemarks));
        return vo;
    }

    @Override
    public List<String> selectExistingCodes(List<String> codes) {
        return deviceInventoryMapper.selectExistingCodes(codes);
    }

    @Override
    public int updateBatchByIds(List<DeviceInventory> list) {
        return deviceInventoryMapper.updateBatchByIds(list);
    }

    @Override
    public List<DeviceInventory> selectByIdsWithStatus(List<Long> ids) {
        return deviceInventoryMapper.selectByIdsWithStatus(ids);
    }


}
